const fetch = require('node-fetch')
const Promise = require('bluebird')
const mysql = require('mysql2/promise')
const _ = require('lodash/fp')
const fs = require('fs')
const $ = require('cheerio')

const parseUrl = (url, emiter) => {
    const map = {
        maka: /maka\.im/,
        eqxiu: /eqxiu\.com/,
        _7192: /7192\.com/
    }

    for (let name in map) {
        if (map[name].test(url)) return store[name](url)
    }

    throw Error('invald url')
}


const storeImg = dir => res => {
    return new Promise((resolve, reject) => {
        try {
            const dest = fs.createWriteStream(dir)
            res.body
                .on('end', () => resolve(dir))
                .on('error', reject)
            return res.body.pipe(dest)
        } catch (error) {
            return reject(error)
        }
    })
}

const convert = page =>
    page.elements.map(elm => {
        let converted = {
            css: elm.css,
            animations: elm.properties.anim ? elm.properties.anim : [],
            content: elm.content
        }
        if (elm.type == 3) {
            converted.content = `<img src=${elm.properties.imgSrc} />`
        } else if (elm.type == 4) {
            let style = '';
            for (let attr in elm.properties.imgStyle) {
                style += `${attr.replace(/[\x41-\x5a]/g, char => '-'+char.toLowerCase())}: ${elm.properties.imgStyle[attr]};`
            }
            converted.content = `<img src=${elm.properties.src} style="${style}" />`
        }

        if (elm.type == 2) {
            converted.content = converted.content.replace(/(<\w+\s?)/, '$1 class="text" ')
        }
        if (converted.animations.map) {
            converted.animations = converted.animations.map(an => ({
                name: convertAnimate(an),
                delay: an.delay + 's',
                count: an.count ? 'infinite' : 1,
                duration: an.duration + 's',
                func: an.linear ? 'linear' : 'ease'
            }))
        }

        return converted
    })


const store = {
    maka: url => {
        const id = url.match(/http:\/\/maka\.im\/store\/preview\/([^\.\n\r]+)/)[1]
        const data_url = `http://api.maka.im/api/storeTemplate/${id}?dataType=pdata`;
        const static_dir = '../xtb/public/collect/maka/'
        const static_url = '/collect/maka/'

        let obj = {}

        const convertImg = elm => {
            const img_url = `http://img1.61xiangce.com/${elm.picid}`
            const file_name = img_url.split('/').pop().replace(/\?.+/, '')

            elm.picid = `${static_url}${file_name}`

            return fetch(img_url).then(storeImg(`${static_dir}${file_name}`))
        }

        fetch(url)
            .then(_ => _.text())
            .then(html => {
                const tmp_info = JSON.parse(html.match(/var STORE_TEMPLATE_INFO = (\{.+\})/)[1])
                obj.title = tmp_info.title
                obj.description = tmp_info.content
                if (obj.id) insert(obj)
            })

        return fetch(data_url)
            .then(_ => _.json())
            .then(data => {
                if (data.code != 200) return Promise.reject('network error')

                obj.collection = JSON.stringify(data)
                obj.raw_id = `2_${id}`
                const res = Promise.all(
                    _(data.data.pdata.json)
                        .map('content')
                        .flatten()
                        .filter(elm => elm.type === 'pic')
                        .map(convertImg)
                )
                if (obj.title) insert(obj)
                return res
            })
            .catch(console.error)
    },
    eqxiu: url => {
        return fetch(url)
            .then(_ => _.text())
            .then(html => {
                const [, id, title] = html.match(/<h2 class="e_name" productId = '\d+' sourceId = '(\d+)'[^>]+>([^<]+)<\/h2>/)
                // let description = html.match(/<label>样例描述：<\/label> <span>([^<]+)<\/span>/)
                // description = description[1] ? description[1] : '';
                const data_url = `http://s1.eqxiu.com/eqs/page/${id}`
                const static_dir = '../xtb/public/collect/eqxiu/'
                const static_url = '/collect/eqxiu/'
                const base_url = 'http://res.eqh5.com/'

                if (!id) throw Error('invald url')

                return fetch(data_url)
                    .then(_ => _.json())
                    .then(obj => {
                        const convertImg = elm => {
                            let src = elm.type == 3 ? elm.properties.imgSrc : elm.properties.src
                            src = /https?:/.test(src) ? src : base_url + src
                            const file_name = src.split('/').pop().replace(/\?.+/, '')
                            elm.properties.src = elm.properties.imgSrc = `${static_url}${file_name}`
                            return fetch(src).then(storeImg(`${static_dir}${file_name}`))

                        }

                        const reqs = Promise.all(
                            _(obj.list)
                                .map('elements')
                                .flatten()
                                .filter(elm => elm.type == 3 || elm.type == 4)
                                .map(convertImg)
                        )
                            .catch(console.error)

                        insert({
                            title: title,
                            collection: JSON.stringify(obj),
                            description: '',
                            raw_id: `1_${id}`,
                            json: JSON.stringify(obj.list.map(convert))
                        })

                        return reqs
                    })
            })
    },

    _7192: url => {
        const id = url.match(/http:\/\/wp\.7192\.com\/v\/wedding\/(\d+)\.html/)[1]
        const base_url = 'http://wp.7192.com'
        const static_dir = '../xtb/public/collect/7192/'
        const static_url = '/collect/7192/'

        if (!id) throw Error('invald url')

        const data_url = `http://wp.7192.com/jsonwedding/${id}.html`

        return fetch(data_url)
            .then(_ => _.json())
            .then(obj => {

                const convertImg = elm => {
                    let src = elm.type == 3 ? elm.properties.imgSrc : elm.properties.src
                    src = /https?:/.test(src) ? src : base_url + src
                    const file_name = src.split('/').pop().replace(/\?.+/, '')
                    elm.properties.src = elm.properties.imgSrc = `${static_url}${file_name}`
                    return fetch(src).then(storeImg(`${static_dir}${file_name}`))

                }

                const reqs = Promise.all(
                    _(obj.list)
                        .map('elements')
                        .flatten()
                        .filter(elm => elm.type == 3 || elm.type == 4)
                        .map(convertImg)
                )
                    .catch(console.error)


                insert({
                    title: obj.obj.name,
                    collection: JSON.stringify(obj),
                    description: '',
                    raw_id: `1_${id}`,
                    json: JSON.stringify(obj.list.map(convert))
                })

                return reqs
            })
    }
}

const insert = obj => {
    const cols = ['title', 'description', 'raw_id', 'collection', 'json']
    return mysql
        .createConnection({ host: 'localhost', user: 'root', password: 'root', database: 'xtb', Promise: Promise })
        .then(con =>
            con
                .query(`INSERT INTO templates(${cols.join(',')}) VALUES(${cols.map(_ => '?').join(',')})`, cols.map(col => obj[col]))
                .then(_ => con.end())
        )
}

module.exports = parseUrl


const convertAnimate = function (a) {
    var b, c, d = parseInt(a.type, 10);
    return 0 === d && (b = "fadeIn"), 1 === d && (c = parseInt(a.direction, 10), 0 === c && (b = "fadeInLeft"), 1 === c && (b = "fadeInDown"), 2 === c && (b = "fadeInRight"), 3 === c && (b = "fadeInUp")), 6 === d && (b = "wobble"), 5 === d && (b = "rubberBand"), 7 === d && (b = "rotateIn"), 8 === d && (b = "flip"), 9 === d && (b = "swing"), 2 === d && (c = parseInt(a.direction, 10), 0 === c && (b = "bounceInLeft"), 1 === c && (b = "bounceInDown"), 2 === c && (b = "bounceInRight"), 3 === c && (b = "bounceInUp")), 3 === d && (b = "bounceIn"), 4 === d && (b = "zoomIn"), 41 === d && (b = "zoomInRoll"), 51 === d && (b = "filterSepia"), 52 === d && (b = "filterGrayScale"), 53 === d && (b = "filterBlur"), 54 === d && (b = "filterInvert"), 55 === d && (b = "filterSaturate"), 56 === d && (b = "filterContrast"), 57 === d && (b = "filterBrightness"), 58 === d && (b = "filterHueRotate"), 59 === d && (b = "flash"), 61 === d && (b = "showWaver"), 62 === d && (b = "showBreath"), 63 === d && (b = "showWaver2"), 10 === d && (b = "fadeOut"), 11 === d && (b = "flipOutY"), 12 === d && (b = "rollIn"), 13 === d && (b = "lightSpeedIn"), 14 === d && (b = "bounceOut"), 15 === d && (b = "rollOut"), 16 === d && (b = "lightSpeedOut"), 17 === d && (c = parseInt(a.direction, 10), 0 === c && (b = "fadeOutRight"), 1 === c && (b = "fadeOutDown"), 2 === c && (b = "fadeOutLeft"), 3 === c && (b = "fadeOutUp")), 18 === d && (b = "zoomOut"), 19 === d && (c = parseInt(a.direction, 10), 0 === c && (b = "bounceOutRight"), 1 === c && (b = "bounceOutDown"), 2 === c && (b = "bounceOutLeft"), 3 === c && (b = "bounceOutUp")), 20 === d && (b = "flipInY"), 21 === d && (b = "tada"), 23 === d && (b = "hinge"), 22 === d && (b = "jello"), 66 === d && (b = "jello2"), 26 === d && (b = "twisterInDown"), 65 === d && (b = "twisterInDown2"), 27 === d && (b = "puffIn"), 28 === d && (b = "puffOut"), 29 === d && (b = "slideDown"), 67 === d && (b = "slideUp3"), 68 === d && (b = "flipInY2"), 69 === d && (b = "incline"), 70 === d && (b = "stagger"), 71 === d && (b = "shadow1"), 72 === d && (b = "shadow2"), 73 === d && (b = "flashx1"), 74 === d && (b = "flashx2"), 75 === d && (b = "change1"), 76 === d && (b = "entrance"), 77 === d && (b = "flipInx"), 78 === d && (b = "flipInxy"), 79 === d && (b = "diffusion"), 80 === d && (b = "bachelordom01"), 81 === d && (b = "earthquake"), 82 === d && (b = "rotate03"), 83 === d && (b = "immigration"), 84 === d && (b = "immigration2"), 85 === d && (b = "towards1"), 86 === d && (b = "towards2"), 87 === d && (b = "towards3"), 88 === d && (b = "shakedong"), 89 === d && (b = "Shrinko"), 90 === d && (b = "immigration3"), 91 === d && (b = "immigration4"), 92 === d && (b = "flicker"), 93 === d && (b = "searchlight"), 94 === d && (b = "rotatea3"), 95 === d && (b = "swing2"), 96 === d && (b = "vague"), 97 === d && (b = "entrance2"), 98 === d && (b = "changea2"), 99 === d && (b = "changea3"), 100 === d && (b = "changea4"), 101 === d && (b = "movement"), 102 === d && (b = "swingshuo"), 103 === d && (b = "filter142"), 104 === d && (b = "filter143"), 30 === d && (b = "slideUp"), 64 === d && (b = "slideUp2"), 24 === d && (b = "flipInX"), 25 === d && (b = "flipOutX"), 31 === d && (b = "twisterInUp"), 32 == d && (b = "vanishOut"), 33 == d && (b = "vanishIn"), b
}